<?php
// +----------------------------------------------------------------------
// | 云静Admin
// +----------------------------------------------------------------------
// | Copyright (c) 2019-2020 http://www.iyunj.cn
// +----------------------------------------------------------------------
// | 云静Admin提供个人非商业用途免费使用。
// +----------------------------------------------------------------------
// | Author: Uncle-L <1732983738@qq.com>
// +----------------------------------------------------------------------
// | 应用的公共函数库
// +----------------------------------------------------------------------

use yunj\Config;
use yunj\Validate;
use think\Response;
use think\response\View;
use think\facade\Request;
use yunj\enum\TipsTemplet;
use yunj\builder\YunjForm;
use yunj\builder\YunjTable;
use yunj\builder\YunjImport;
use think\response\Redirect;
use yunj\Config as YunjConfig;
use yunj\builder\Builder as YunjBuilder;
use think\exception\HttpResponseException;

if (!function_exists('yunj_config')) {
    /**
     * Notes: 基础配置
     * Author: Uncle-L
     * Date: 2020/10/20
     * Time: 14:45
     * @param string $key [配置参数名，第一级为配置文件名。支持多级配置 .号分割。如：yunj_config('errcode.10000')]
     * @param null $default [默认值]
     * @return mixed
     */
    function yunj_config(string $key, $default = null) {
        return Config::get($key, $default, YUNJ_PATH . "config/", YUNJ_VENDOR_SRC_PATH . "config/");
    }
}

if (!function_exists('view_template')) {
    /**
     * Notes: 视图模板地址
     * Author: Uncle-L
     * Date: 2021/11/3
     * Time: 16:02
     * @param string $template
     * @return string
     */
    function view_template(string $template): string {
        $path = "../" . YUNJ_VENDOR_SHORT_PATH . "src/view/";
        $template .= substr($template, -5) !== ".html" ? ".html" : "";
        return $path . $template;
    }
}

if (!function_exists('YF')) {
    /**
     * Notes: 创建一个表单构建器实例
     * Author: Uncle-L
     * Date: 2021/10/9
     * Time: 11:59
     * @param string $id
     * @param array $args
     * @return YunjForm
     */
    function YF(string $id, array $args = []): YunjForm {
        return new YunjForm($id, $args);
    }
}

if (!function_exists('YT')) {
    /**
     * Notes: 创建一个表格构建器实例
     * Author: Uncle-L
     * Date: 2021/10/9
     * Time: 12:00
     * @param string $id
     * @param array $args
     * @return YunjTable
     */
    function YT(string $id, array $args = []): YunjTable {
        return new YunjTable($id, $args);
    }
}

if (!function_exists('YI')) {
    /**
     * Notes: 创建一个导入构建器实例
     * Author: Uncle-L
     * Date: 2021/10/9
     * Time: 12:00
     * @param string $id
     * @param array $args
     * @return YunjImport
     */
    function YI(string $id, array $args = []): YunjImport {
        return new YunjImport($id, $args);
    }
}

if (!function_exists('view_builder')) {
    /**
     * 渲染表格模板输出
     * @param YunjBuilder $builder 构建器实例
     * @param string $template 模板文件
     * @param array $vars 模板变量
     * @param int $code 状态码
     * @param callable $filter 内容过滤
     * @return View
     * @throws \Exception
     */
    function view_builder(YunjBuilder $builder, string $template, array $vars = [], int $code = 200, callable $filter = null): View {
        if (Request::isAjax()) return $builder->async();
        $builderType = $builder->getType();
        $builderViewArgs = $builder->viewArgs();
        $builderScriptFileList = $builder->getScriptFileList();
        $builderId = $builder->getId();
        $vars = [
                "builderId" => $builderId,
                $builderType => [$builderId => $builderViewArgs],
                "scriptFileList" => $builderScriptFileList
            ] + $vars;
        $template = view_template($template);
        return view($template, $vars, $code, $filter);
    }
}

if (!function_exists('view_form')) {
    /**
     * 渲染表单模板输出
     * @param YunjForm $builder 表单构建器实例
     * @param array $vars 模板变量
     * @param int $code 状态码
     * @param callable $filter 内容过滤
     * @return View
     * @throws \Exception
     */
    function view_form(YunjForm $builder, array $vars = [], int $code = 200, callable $filter = null): View {
        return view_builder($builder, "admin/template/form", $vars, $code, $filter);
    }
}

if (!function_exists('view_table')) {
    /**
     * 渲染表格模板输出
     * @param YunjTable $builder 表格构建器实例
     * @param array $vars 模板变量
     * @param int $code 状态码
     * @param callable $filter 内容过滤
     * @return View
     * @throws \Exception
     */
    function view_table(YunjTable $builder, array $vars = [], int $code = 200, callable $filter = null): View {
        return view_builder($builder, "admin/template/table", $vars, $code, $filter);
    }
}

if (!function_exists('view_import')) {
    /**
     * 渲染导入模板输出
     * @param YunjImport $builder 导入构建器实例
     * @param array $vars 模板变量
     * @param int $code 状态码
     * @param callable $filter 内容过滤
     * @return View
     * @throws \Exception
     */
    function view_import(YunjImport $builder, array $vars = [], int $code = 200, callable $filter = null): View {
        return view_builder($builder, "admin/template/import", $vars, $code, $filter);
    }
}

/****************************************************** 跳转 ******************************************************/
if (!function_exists('url_tips')) {
    /**
     * Notes: 提示页面地址
     * Author: Uncle-L
     * Date: 2020/10/21
     * Time: 17:54
     * @param TipsTemplet|null $templet [提示模板]
     * @param string $msg [提示消息]
     * @return string
     */
    function url_tips(TipsTemplet $templet = null, string $msg = ''): string {
        /** @var TipsTemplet $templet */
        $templet = $templet ?: TipsTemplet::ERROR();
        $vars = input('get.');
        $vars['templet'] = $templet->getValue();
        if ($msg && is_string($msg)) $vars['msg'] = $msg;
        return url("/admin/tips") . "?" . http_build_query($vars);
    }
}

if (!function_exists('redirect_tips')) {
    /**
     * Notes: 重定向到提示页
     * Author: Uncle-L
     * Date: 2020/10/21
     * Time: 18:09
     * @param TipsTemplet|null $templet [提示模板]
     * @param string $msg [提示消息]
     * @return Redirect
     */
    function redirect_tips(TipsTemplet $templet = null, string $msg = ''): Redirect {
        return redirect(url_tips($templet, $msg));
    }
}

if (!function_exists('throw_redirect')) {
    /**
     * Notes: 抛出重定向
     * Author: Uncle-L
     * Date: 2021/10/19
     * Time: 14:53
     * @param string $url
     */
    function throw_redirect(string $url): void {
        // 重定向到当前地址不行
        if (strstr(Request::url(), $url)) return;
        header('content-type:text/html;charset=uft-8');
        header('location:' . $url);
        exit;
    }
}

/****************************************************** 输出 ******************************************************/

if (!function_exists('response_msg')) {
    /**
     * Notes: 返回错误码对应消息
     * Author: Uncle-L
     * Date: 2020/7/20
     * Time: 13:56
     * @param int $errcode
     * @param string $msg
     * @return string
     */
    function response_msg(Int $errcode = 10000, string $msg = '') {
        return $errcode < 90000 ? YunjConfig::get('errcode.' . $errcode, $msg) : yunj_config('errcode.' . $errcode, $msg);
    }
}

if (!function_exists('response_json')) {
    /**
     * Notes: 返回固定格式json数据
     * Author: Uncle-L
     * Date: 2020/7/8
     * Time: 22:19
     * @param int $errcode
     * @param string $msg
     * @param mixed $data
     * @return \think\response\Json
     */
    function response_json(Int $errcode = 10000, string $msg = '', $data = null) {
        $msg = $msg ?: response_msg($errcode) ?: '';
        $result = ['errcode' => $errcode, 'msg' => $msg, 'data' => $data];
        return json($result);
    }
}

if (!function_exists('success_json')) {
    /**
     * Notes: 返回成功格式的json数据
     * Author: Uncle-L
     * Date: 2020/1/14
     * Time: 17:47
     * @param mixed $data
     * @return \think\response\Json
     */
    function success_json($data = null) {
        $msg = response_msg(0);
        return response_json(0, $msg, $data);
    }
}

if (!function_exists('error_json')) {
    /**
     * Notes: 返回失败格式的json数据
     * Author: Uncle-L
     * Date: 2020/1/14
     * Time: 17:49
     * @param string $msg
     * @return \think\response\Json
     */
    function error_json(string $msg = '') {
        $msg = $msg ?: response_msg(10000);
        return response_json(10000, $msg);
    }
}

if (!function_exists('throw_json')) {
    /**
     * Notes: 抛出固定格式json数据
     * Author: Uncle-L
     * Date: 2020/7/8
     * Time: 22:24
     * @param int|Response $errcode
     * @param string $msg
     * @param mixed $data
     */
    function throw_json($errcode = 10000, string $msg = '', $data = null) {
        $response = $errcode instanceof Response ? $errcode : json(['errcode' => $errcode, 'msg' => $msg, 'data' => $data]);
        throw new HttpResponseException($response);
    }
}

if (!function_exists('throw_success_json')) {
    /**
     * Notes: 抛出成功格式的json数据
     * Author: Uncle-L
     * Date: 2020/3/21
     * Time: 18:20
     * @param mixed $data
     */
    function throw_success_json($data = null) {
        $response = success_json($data);
        throw_json($response);
    }
}

if (!function_exists('throw_error_json')) {
    /**
     * Notes: 抛出错误格式的json数据
     * Author: Uncle-L
     * Date: 2020/3/21
     * Time: 18:21
     * @param string $msg
     */
    function throw_error_json(string $msg = '') {
        $response = error_json($msg);
        throw_json($response);
    }
}

/****************************************************** 验证 ******************************************************/

if (!function_exists('data_validate')) {
    /**
     * Notes: 数据验证
     * Author: Uncle-L
     * Date: 2021/10/21
     * Time: 14:22
     * @param Validate $validate [验证器]
     * @param array $rule [字段规则]
     * @param array $field [字段描述]
     * @param array $data [待验证数据]
     * @param string $scene [验证环境]
     * @return bool
     */
    function data_validate(Validate &$validate, array $rule, array $field, array &$data, string $scene): bool {
        // 设置参数
        $validate->setAttrRule($rule);
        $validate->setAttrField($field);
        $validate->setAttrScene([$scene => array_keys($rule)]);
        // 开始校验
        $res = $validate->scene($scene)->check($data);
        if ($res) {
            // 验证通过赋值处理后的数据给待处理数据
            $data = $validate->getData();
        }
        // 返回验证结果
        return $res;
    }
}

if (!function_exists('form_data_validate')) {
    /**
     * Notes: 表单数据验证
     * Author: Uncle-L
     * Date: 2021/10/20
     * Time: 18:09
     * @param Validate $validate [验证器]
     * @param array $fields [字段配置]
     * @param array $data [待验证数据]
     * @param string $scene [验证环境]
     * @return bool
     */
    function form_data_validate(Validate &$validate, array $fields, array &$data, string $scene) {
        // 规则
        $attrRule = [];
        // 验证数据描述
        $attrField = [];
        foreach ($fields as $k => $field) {
            if (!isset($field['verify']) || !$field['verify']) continue;
            $attrRule[$k] = $field['verify'];
            $attrField[$k] = isset($field["verifyTitle"]) && $field['verifyTitle'] ? $field['verifyTitle'] : (isset($field["title"]) && $field['title'] ?: $k);
        }
        if (!$attrRule) return true;
        $res = data_validate($validate, $attrRule, $attrField, $data, $scene);
        return $res;
    }
}